package creational.singleton;
import java.io.*;

/**
 * @author hey
 */
public class SingletonDemo{

    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        new Thread(()->{
//            LazySingleton instance = LazySingleton.getInstance();
//            System.out.println(instance);
//        }).start();
//        new Thread(()->{
//            LazySingleton instance = LazySingleton.getInstance();
//            System.out.println(instance);
//        }).start();
//
//
//        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
//        HungrySingleton hungrySingleton01 = HungrySingleton.getInstance();
//        System.out.println(hungrySingleton);
//        System.out.println(hungrySingleton01);


        InnerClassSingleton innerClassSingleton = InnerClassSingleton.getInstance();
        InnerClassSingleton innerClassSingleton01 = InnerClassSingleton.getInstance();
        System.out.println(innerClassSingleton);
        System.out.println(innerClassSingleton01);


        //序列化测试

//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("SingletonDemoInstance"));
//        oos.writeObject(innerClassSingleton);
//        System.out.println(innerClassSingleton);
//        System.out.println(innerClassSingleton01);

//        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("SingletonDemoInstance"));
//        InnerClassSingleton object = ((InnerClassSingleton) ois.readObject());
//        System.out.println(object);
//        System.out.println(innerClassSingleton == object);



    }
}

/**
 * 懒加载模式
 */
class LazySingleton {

    //volatile防止出现字节码创建指令重排序
    private static volatile LazySingleton instance;

    private LazySingleton(){
        System.out.println("LazySingleton--私有构造函数");
    }

    public static LazySingleton getInstance(){
        if (instance == null){
            synchronized (LazySingleton.class){
                if (instance == null){
                    instance = new LazySingleton();
                    return instance;
                }
            }
        }
        return instance;
    }

}

/**
 * 饿汉模式
 * 基于类加载机制
 */
class HungrySingleton{

    private static HungrySingleton instance = new HungrySingleton();

    private HungrySingleton() {
        System.out.println("HungrySingleton--私有构造函数");
    }

    public static HungrySingleton getInstance(){
        return instance;
    }

}

/**
 * 静态内部类方式
 */
class InnerClassSingleton implements Serializable {

    private static final long serialVersionUID = 42L;

    private static class InnerClassHolder{
        private static InnerClassSingleton instance = new InnerClassSingleton();
    }

    private InnerClassSingleton(){
        System.out.println("InnerClassSingleton--私有构造函数");
    }

    public static InnerClassSingleton getInstance(){
        return InnerClassHolder.instance;
    }

    private Object readResolve() throws ObjectStreamException {
        return InnerClassHolder.instance;
    }
}

/**
 * enum模式，支持反射
 */


